Skip to content

Main_cloud#24

Closed
farhanmahee wants to merge 19 commits intofreestyle-sh:mainfrom
farhanmahee:Main_cloud
Closed

Main_cloud#24
farhanmahee wants to merge 19 commits intofreestyle-sh:mainfrom
farhanmahee:Main_cloud

Conversation

@farhanmahee
Copy link

@farhanmahee farhanmahee commented Nov 22, 2025

TL;DR

Pivoted the project from an AI application builder to a comprehensive, production-ready Enterprise Resource Planning (ERP) system for manufacturing and gas distribution.

Why we made these changes

This PR represents a fundamental shift in the project's direction to establish a complete ERP system as the core product. The goal is to provide a full-featured solution tailored for businesses in Bangladesh, covering all major operational areas from inventory and sales to accounting and reporting.

What changed?

  • Project Pivot & Documentation: The README.md was completely rewritten to reflect the new ERP focus. Extensive documentation was added, including ERP_SETUP_GUIDE.md, API_QUICK_REFERENCE.md, a DEPLOYMENT_CHECKLIST.md, and a FEATURE_ROADMAP.md.
  • Backend API: A comprehensive suite of RESTful API endpoints was added under src/app/api/organizations/ to manage all core ERP functions, including Master Data, Inventory, Purchase, Sales, Accounting, and Reporting.
  • Frontend UI: A new frontend application was built under src/app/erp/ with a modular dashboard structure. This includes dedicated pages for each ERP module (Inventory, Purchase, Sales, Accounting, Reports, Masters), a shared ERPLayout, and a new LoginPage.
  • Database: Established the complete database schema for the ERP system in src/db/schema.ts and added the initial Drizzle migration.
  • Core Logic & Utilities:
    • Added erp-utils.ts for centralized business logic, financial calculations, and Bangladesh-specific compliance.
    • Implemented multi-language support for English and Bengali in translations.ts.
  • CI/CD & Infrastructure:
    • Introduced a new GitHub Actions workflow to automatically manage Neon database branches for each pull request.
    • Added .env to .gitignore to protect sensitive credentials.

Validation

  • Manual testing of all new API endpoints is required.
  • The frontend should be tested to ensure all module pages render correctly and are prepared for API integration.
  • The database migration should be verified to apply cleanly on a fresh Neon instance.

Description generated by Mesa. Update settings

…ers, payment receipts, products, purchase orders, sales orders, and reports

- Added GET and POST endpoints for journal vouchers to manage journal entries and ledger updates.
- Implemented payment receipts handling with invoice payment status updates.
- Created product management routes for fetching and adding products.
- Developed purchase order routes with item management and total calculations.
- Added sales order routes for managing sales and associated items.
- Implemented various report generation endpoints for purchase, sales, stock, and trial balance.
- Introduced user management routes with password handling and organization-specific settings.
- Added utility functions for API responses, currency formatting, date formatting, and document number generation.
- Integrated multi-language support for English and Bangla in the application.
…les, masters, and reports

- Created ERP layout with sidebar navigation and user menu
- Developed Masters page for managing master data (customers, suppliers, products, users)
- Implemented Purchase page for tracking purchase orders with statistics and search functionality
- Added Sales page for managing sales orders with analytics and quick actions
- Created Reports page for generating various financial reports with date range filtering
Copy link

@mesa-dot-dev mesa-dot-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performed full review of 74316d1...3037bc1

Analysis

  1. Critical Security Vulnerability: All API routes lack authentication/authorization middleware, leaving financial operations completely exposed to unauthorized access. Without session validation or identity verification, anyone can access organization data by guessing UUIDs.

  2. Financial Calculation Errors: The weighted average cost formula is mathematically incorrect, which will cause inventory valuation errors. Bangladesh fiscal year configuration is also wrong (set to Jan-Dec instead of Jul-Jun), affecting all fiscal reporting and compliance.

  3. Database Transaction Issues: Critical multi-step operations (GRN creation, journal vouchers, invoices, payments) lack atomicity through database transactions, risking data corruption and accounting inconsistencies under concurrent operations.

  4. Incorrect Accounting Logic: Journal voucher routes apply the same balance calculation formula universally, failing to account for different account types (asset/liability/equity), which will result in incorrect financial statements.

  5. Missing Input Validation: The system lacks comprehensive input validation across API routes, creating vulnerabilities to injection attacks, calculation errors, and data corruption through malformed payloads.

Tip

Help

Slash Commands:

  • /review - Request a full code review
  • /review latest - Review only changes since the last review
  • /describe - Generate PR description. This will update the PR body or issue comment depending on your configuration
  • /help - Get help with Mesa commands and configuration options

53 files reviewed | 7 comments | Edit Agent SettingsRead Docs

.select()
.from(stockBalanceTable)
.where(
eq(stockBalanceTable.warehouseId, warehouseId) &
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High

Critical bug: Using bitwise AND operator (&) instead of Drizzle's and() function. This will cause a runtime error or incorrect query behavior.

Should be:

import { eq, and } from "drizzle-orm";
// ...
.where(
  and(
    eq(stockBalanceTable.warehouseId, warehouseId),
    eq(stockBalanceTable.productId, item.productId)
  )
)

Agent: 🤖 General • Fix in Cursor

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: freestyle-sh/Adorable#24
File: src/app/api/organizations/[orgId]/grn/route.ts#L83
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
Critical bug: Using bitwise AND operator (&) instead of Drizzle's `and()` function. This will cause a runtime error or incorrect query behavior.

Should be:
```typescript
import { eq, and } from "drizzle-orm";
// ...
.where(
  and(
    eq(stockBalanceTable.warehouseId, warehouseId),
    eq(stockBalanceTable.productId, item.productId)
  )
)

</details>

): number {
const totalQuantity = previousQuantity + newQuantity;
if (totalQuantity === 0) return 0;
return (previousCost + newCost) / totalQuantity;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High

Critical financial calculation error: The weighted average cost formula is mathematically incorrect. This calculates (previousCost + newCost) / totalQuantity, which treats costs as totals rather than per-unit costs.

Correct formula should be:

return ((previousQuantity * previousCost) + (newQuantity * newCost)) / totalQuantity;

Example of the bug:

  • Previous: 100 units @ $10/unit = $1,000 total
  • New: 50 units @ $20/unit = $1,000 total
  • Current formula: (10 + 20) / 150 = $0.20/unit ❌
  • Correct formula: (10010 + 5020) / 150 = $13.33/unit ✓

This will cause significant inventory valuation errors in financial statements.

Agent: 🤖 General • Fix in Cursor

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: freestyle-sh/Adorable#24
File: src/lib/erp-utils.ts#L65
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
Critical financial calculation error: The weighted average cost formula is mathematically incorrect. This calculates (previousCost + newCost) / totalQuantity, which treats costs as totals rather than per-unit costs.

Correct formula should be:
```typescript
return ((previousQuantity * previousCost) + (newQuantity * newCost)) / totalQuantity;

Example of the bug:

  • Previous: 100 units @ $10/unit = $1,000 total
  • New: 50 units @ $20/unit = $1,000 total
  • Current formula: (10 + 20) / 150 = $0.20/unit ❌
  • Correct formula: (10010 + 5020) / 150 = $13.33/unit ✓

This will cause significant inventory valuation errors in financial statements.


</details>


// Create GRN items and update stock balance
if (items && items.length > 0) {
for (const item of items) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High

Missing database transaction: The entire GRN creation and stock update process (lines 66-118) should be wrapped in a database transaction to ensure atomicity. If any stock update fails, partial data will be left in an inconsistent state.

Recommended fix:

await db.transaction(async (tx) => {
  // Move all insert/update operations here
  for (const item of items) {
    // ...
  }
});

Agent: 🤖 General • Fix in Cursor

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: freestyle-sh/Adorable#24
File: src/app/api/organizations/[orgId]/grn/route.ts#L66
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
Missing database transaction: The entire GRN creation and stock update process (lines 66-118) should be wrapped in a database transaction to ensure atomicity. If any stock update fails, partial data will be left in an inconsistent state.

Recommended fix:
```typescript
await db.transaction(async (tx) => {
  // Move all insert/update operations here
  for (const item of items) {
    // ...
  }
});

</details>

.returning();

// Create journal entries and ledger entries
if (entries && entries.length > 0) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High

Missing database transaction: All journal entries, ledger entries, and account balance updates must be atomic. If any step fails after line 65, you'll have partial entries that corrupt the general ledger.

Wrap the entire operation in a transaction:

await db.transaction(async (tx) => {
  // Move all operations here
});

Agent: 🤖 General • Fix in Cursor

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: freestyle-sh/Adorable#24
File: src/app/api/organizations/[orgId]/journal-vouchers/route.ts#L65
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
Missing database transaction: All journal entries, ledger entries, and account balance updates must be atomic. If any step fails after line 65, you'll have partial entries that corrupt the general ledger.

Wrap the entire operation in a transaction:
```typescript
await db.transaction(async (tx) => {
  // Move all operations here
});

</details>

.where(eq(chartOfAccountsTable.id, entry.accountId));

if (account.length > 0) {
const newBalance =
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High

Account balance calculation error: This logic doesn't consider the account's normal balance type. In double-entry accounting:

  • Debits increase: Assets, Expenses
  • Credits increase: Liabilities, Equity, Revenue

The current formula (balance + debit - credit) only works for asset accounts. Should retrieve account type and apply appropriate logic, otherwise financial statements will be incorrect.

Agent: 🤖 General • Fix in Cursor

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: freestyle-sh/Adorable#24
File: src/app/api/organizations/[orgId]/journal-vouchers/route.ts#L84
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
Account balance calculation error: This logic doesn't consider the account's normal balance type. In double-entry accounting:
- Debits increase: Assets, Expenses
- Credits increase: Liabilities, Equity, Revenue

The current formula (balance + debit - credit) only works for asset accounts. Should retrieve account type and apply appropriate logic, otherwise financial statements will be incorrect.

let totalCredit = "0";

if (entries && entries.length > 0) {
entries.forEach((entry: any) => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High

Missing double-entry validation: Before creating the journal voucher, verify that totalDebit equals totalCredit. Unbalanced entries violate fundamental accounting principles and will corrupt financial statements.

Add validation:

if (parseFloat(totalDebit) !== parseFloat(totalCredit)) {
  return NextResponse.json(
    { error: "Journal entries must be balanced: debits must equal credits" },
    { status: 400 }
  );
}

Agent: 🤖 General • Fix in Cursor

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: freestyle-sh/Adorable#24
File: src/app/api/organizations/[orgId]/journal-vouchers/route.ts#L44
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
Missing double-entry validation: Before creating the journal voucher, verify that totalDebit equals totalCredit. Unbalanced entries violate fundamental accounting principles and will corrupt financial statements.

Add validation:
```typescript
if (parseFloat(totalDebit) !== parseFloat(totalCredit)) {
  return NextResponse.json(
    { error: "Journal entries must be balanced: debits must equal credits" },
    { status: 400 }
  );
}

</details>

@farhanmahee farhanmahee closed this by deleting the head repository Nov 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant